package com.mlnx.device.syn;


import com.mlnx.bptp.BpPacket;
import com.mlnx.common.entity.Response;
import com.mlnx.common.utils.MyLog;
import com.mlnx.device.pojo.dto.SynData;
import com.mlnx.device.session.SessionManagerFactory;
import com.mlnx.device.session.manager.MutilDeviceSessionManager;
import com.mlnx.device.util.CmdUtils;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;



/**
 * 同步数据管理类
 *
 * @author zzb
 * @create 2019/10/10 17:17
 */
public class SynDataManage {
    private MyLog log = MyLog.getLog(this.getClass());
    private Map<String, SynData> synMap = new ConcurrentHashMap<String, SynData>();
    private static SynDataManage instance;

    private MutilDeviceSessionManager sessionManager = SessionManagerFactory.getInstance().getMutilDeviceSessionManager();


    public static SynDataManage getInstance() {
        if (instance == null) {
            synchronized (SynDataManage.class) {
                if (instance == null) {
                    instance = new SynDataManage();
                }
            }
        }
        return instance;
    }

    public SynDataManage() {
        init();
    }


    private void init() {
        Thread task = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    for (String deviceId : synMap.keySet()) {
                        SynData synData = synMap.get(deviceId);
                        if (getOverTime(deviceId) > 7) {
                            synData.getResponseDeferredResult().setResult(new Response("设备掉线 同步失败"));
                            synMap.remove(deviceId);
                            continue;
                        }

                        if (synData.isCurrentSign() || System.currentTimeMillis() - synData.getCurrentTime() > 1000) {
                            if( synData.getCurrentTime()!=null){
                                if (System.currentTimeMillis() - synData.getCurrentTime() > 1000) {
                                    addOverTime(deviceId);
                                    log.info("设备未回复次数："+synData.getOverTime());
                                }
                            }

                            if (synData.getTotal() == null) {

                                askTotal(deviceId);

                            } else if (synData.getTotal() != null) {
                                if (synData.getTotal() <= synData.getCurrent()) {
                                    synData.getResponseDeferredResult().setResult(new Response());
                                    synMap.remove(deviceId);
                                    log.info("同步成功 移除:deviceId：" + deviceId);

                                } else {
                                    if (System.currentTimeMillis() - synData.getCurrentTime() < 1000) {
                                        askNext(synData.getCurrent(), deviceId);
                                        log.info("条数：" + synData.getCurrent());
                                    } else {
                                        askNext(synData.getCurrent() - 1, deviceId);
                                        log.info("未获得设备响应 继续询问条数：" + (synData.getCurrent() - 1));
                                    }
                                }
                            }


                        }
                    }
                    try {
                        Thread.sleep(5);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        });
        task.start();
    }

    public void askNext(Integer currentIndex, String deviceId) {

        SynData synData = synMap.get(deviceId);
        Channel channel = sessionManager.getChannel(deviceId);
        if (channel != null) {
            if (synData != null) {
                if (synData.getTotal() > (currentIndex) && synData.getCurrent().equals(currentIndex)) {
                    //获取第currentIndex+1条记录
                    channel.writeAndFlush(Unpooled.copiedBuffer(CmdUtils.getNum(currentIndex)));
                    synData.setCurrentTime(System.currentTimeMillis());
                    synData.setCurrent(currentIndex + 1);
                    synData.setCurrentSign(false);
                    synMap.put(deviceId, synData);

                }
            }

        }
    }

    public void askTotal(String deviceId) {
        BpPacket bpPacket = new BpPacket();
        bpPacket.getBody().setSynData("1");
        Channel channel = sessionManager.getChannel(deviceId);
        SynData synData = synMap.get(deviceId);
        synData.setCurrentTime(System.currentTimeMillis());
        synData.setCurrentSign(false);
        synMap.put(deviceId, synData);
        if (channel != null) {
            channel.writeAndFlush(Unpooled.copiedBuffer(bpPacket.encode()));

            log.info("询问设备：" + deviceId + "总记录数");
        }
    }

    /**
     * 根据设备ID获得SynData
     *
     * @param deviceId
     * @return
     */
    public SynData get(String deviceId) {
        return synMap.get(deviceId);
    }




    /**
     * 将SynData通过设备ID放入MAP中
     *
     * @param deviceId
     * @return
     */
    public void add(String deviceId, SynData synData) {
        synMap.put(deviceId, synData);
    }

    /**
     * 增加OVERTIME数量
     *
     * @param deviceId
     * @return
     */
    public Integer addOverTime(String deviceId) {
        SynData synData = synMap.get(deviceId);
        synData.setOverTime(synData.getOverTime() + 1);
        synMap.put(deviceId, synData);
        return synData.getOverTime();
    }

    /**
     * 获得OVERTIME数量
     *
     * @param deviceId
     * @return
     */
    public Integer getOverTime(String deviceId) {
        return synMap.get(deviceId).getOverTime();
    }

    /**
     * 设置SYNDATA的总数
     *
     * @param deviceId
     * @param total
     * @return
     */
    public void setTotal(String deviceId, Integer total) {
        SynData synData = synMap.get(deviceId);
        synData.setTotal(Integer.valueOf(total));
        synData.setCurrent(0);
        synData.setCurrentTime(System.currentTimeMillis());
        synData.setCurrentSign(true);
        synMap.put(deviceId, synData);

    }

    /**
     * 获得对应条的数据
     *
     * @param deviceId
     * @param current
     * @return
     */
    public void verifyData(String deviceId, Integer current) {

        SynData synData = synMap.get(deviceId);
        if (synData != null) {
            if (current.equals(synData.getCurrent())) {
                synData.setCurrentSign(true);
            }
            synMap.put(deviceId, synData);
        }


    }

}
